﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices.WindowsRuntime;
using Windows.Foundation;
using Windows.Foundation.Collections;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Controls.Primitives;
using Windows.UI.Xaml.Data;
using Windows.UI.Xaml.Input;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Navigation;

using Windows.Storage;
using Windows.Web;
using System.Threading;
using System.Threading.Tasks;
using Windows.UI.Xaml.Media.Imaging;
using Windows.ApplicationModel.Activation;
using System.Diagnostics;

// The Blank Page item template is documented at http://go.microsoft.com/fwlink/?LinkId=234238

namespace VoiceSnap
{
    /// <summary>
    /// An empty page that can be used on its own or navigated to within a Frame.
    /// </summary>
    public sealed partial class ShowMe : Page
    {
        public ShowMe()
        {
            this.InitializeComponent();
        }

        /// <summary>
        /// Invoked when this page is about to be displayed in a Frame.
        /// </summary>
        /// <param name="e">Event data that describes how this page was reached.
        /// This parameter is typically used to configure the page.</param>
        protected async override void OnNavigatedTo(NavigationEventArgs e)
        {
            searchBox.Text = "";
            searchButton.IsEnabled = false;
            searchBox.IsEnabled = false;

            // Populate photo album of the device with images packages with this application
            string containerName = "VoiceSnapAppContainer";
            string settingName = "PopulatedPhotoAlbum";
            string settingValue = "Yes";

            ApplicationDataContainer localSettings = Windows.Storage.ApplicationData.Current.LocalSettings;
            ApplicationDataContainer container = localSettings.CreateContainer(containerName, ApplicationDataCreateDisposition.Always);

            // Load the images from App local data into photo library on the first run of App.
            if (!localSettings.Containers[containerName].Values.ContainsKey(settingName))
            {
                searchCriteria.Text = "Copying sample photos to the picture library...";        
                await AppUtil.PopulatePhotoAlbum();
                localSettings.Containers[containerName].Values[settingName] = settingValue;
                searchCriteria.Text = "";
            }                 
            
            // Consume Voice command arguments which were passed down to this page on activation.
            VoiceCommandActivatedEventArgs vcArgs = e.Parameter as VoiceCommandActivatedEventArgs;
            if (vcArgs != null)
            {
                IReadOnlyList<string> recognizedVoiceCommandPhrases;
                if (vcArgs.Result.SemanticInterpretation.Properties.TryGetValue("PhotoTag", out recognizedVoiceCommandPhrases))
                {
                    searchBox.Text = recognizedVoiceCommandPhrases.First();
                }
            }

            searchButton.IsEnabled = true;
            searchBox.IsEnabled = true;
            
            await SearchPhotos();
        }

        /// <summary>
        /// Search photos on Saved pictures folder on you phone's photo library based on the search criteria in search box
        /// If no criteria is provided, this will return all photos from the folder.
        /// </summary>
        /// <returns></returns>
        private async Task SearchPhotos()
        {
            searchButton.IsEnabled = false;
            searchBox.IsEnabled = false;
            searchCriteria.Text = "Just a minute, getting your photos...";
            
            var tagToSearch = searchBox.Text;
                
            // clear up stack panel of photos.
            stackPanel.Children.Clear();
     
            // Look up saved pictures on the phone that match search criteria.
            bool atleastOneMatch = false;
            var allFiles = await Constants.ImageSearchLocation.GetFilesAsync();

            foreach (StorageFile currFile in allFiles)
            {
                var currFileProps = await currFile.Properties.GetImagePropertiesAsync();
                if (currFileProps.Keywords.Contains(tagToSearch, StringComparer.OrdinalIgnoreCase) || tagToSearch == "..." || tagToSearch == "")
                {
                    // Get photo as a BitmapImage
                    var photoStream = await currFile.OpenAsync(Windows.Storage.FileAccessMode.Read);
                    BitmapImage bmpImage = new BitmapImage();
                    bmpImage.SetSource(photoStream);

                    // Create new image element for the photo.
                    Image currImg = new Image();
                    currImg.Source = bmpImage;
                    currImg.Stretch = Stretch.Uniform;
                    currImg.Margin = new Thickness(0, 0, 0, 5);

                    // Append image to the stack panel for rendering.
                    stackPanel.Children.Add(currImg);

                    atleastOneMatch = true;
                }
            }
                
            // If there is no search criteria in search box, i.e. "", we will be showing all photos from saved pictures folder.
            // If voice command was unable to resolve the phrase, it identifies  phrase as "..."
            if (tagToSearch == "..." || tagToSearch == "")
            {
                searchCriteria.Text = "Here are your photos!";
            }
            else if (atleastOneMatch)
            {
                searchCriteria.Text = "Here are your photos of " + tagToSearch + "!";
            }
            else 
            {
                searchCriteria.Text = "You don't have any photos for " + tagToSearch + " on this device :(";
            }

            searchButton.IsEnabled = true;
            searchBox.IsEnabled = true;
        }

        /// <summary>
        /// On click event behind search button.
        /// This triggers the photo search based on search criteria specified in search box.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private async void SearchButton(object sender, RoutedEventArgs e)
        {
            await SearchPhotos();
        }

        /// <summary>
        /// Navigate to the application page with Camera and photo shoot functionality.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void NavigateToCamera(object sender, RoutedEventArgs e)
        {
            Frame rootFrame = Window.Current.Content as Frame;
            Debug.Assert(rootFrame.Navigate(typeof(MainPage)), "Failed to create initial page");
        }

        /// <summary>
        /// Tracks key press event on search box.
        /// On receiving "enter" key in search box, this will trigger search action.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private async void SearchBox_KeyDown(object sender, KeyRoutedEventArgs e)
        {
            if (e.Key == Windows.System.VirtualKey.Enter)
            {
                await SearchPhotos();
            }
        }

    }
}
